home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / mg / rib / mgrib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-07  |  27.0 KB  |  1,013 lines

  1. #include "mg.h"
  2. #include "mgP.h"
  3. #include "mgribP.h"
  4. #include "mgribshade.h"
  5. #include "mgribtoken.h"
  6. #include <stdio.h>
  7. #include <sys/types.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <time.h>
  11.  
  12. mgcontext * mgrib_ctxcreate(int a1, ...);
  13. void        mgrib_ctxset( int a1, ...  );
  14. int        mgrib_feature( int feature );
  15. void        mgrib_ctxdelete( mgcontext *ctx );
  16. int        mgrib_ctxget( int attr, void* valueptr );
  17. int        mgrib_ctxselect( mgcontext *ctx );
  18. void        mgrib_sync( void );
  19. void        mgrib_worldbegin( void );
  20. void        mgrib_worldend( void );
  21. void        mgrib_reshapeviewport( void );
  22. void        mgrib_identity( void );
  23. void        mgrib_transform( Transform T );
  24. int        mgrib_pushtransform( void );
  25. int        mgrib_poptransform( void );
  26. void        mgrib_settransform( Transform T );
  27. int        mgrib_pushappearance( void );
  28. int        mgrib_popappearance( void );
  29. Appearance  *mgrib_setappearance( Appearance* app, int merge);
  30. Appearance  *mgrib_getappearance( void );
  31. int        mgrib_setcamera( Camera* cam );
  32. mgribcontext *mgrib_newcontext( mgribcontext *ctx );
  33.  
  34. extern void  mgrib_polygon();
  35. extern void  mgrib_mesh();
  36. extern void  mgrib_line();
  37. extern void  mgrib_polyline();
  38. extern void  mgrib_polylist();
  39. extern void  mgrib_bezier();
  40.  
  41. void _mgrib_ctxset(int a1, va_list *alist);
  42.  
  43. WnWindow *mgribwindow(WnWindow *win);
  44.  
  45. struct mgfuncs mgribfuncs = {
  46.   MGD_RIB,
  47.   mgdevice_RIB,
  48.   mgrib_feature,
  49.   (mgcontext *(*)())mgrib_ctxcreate,
  50.   mgrib_ctxdelete,
  51.   (void (*)())mgrib_ctxset,
  52.   mgrib_ctxget,
  53.   mgrib_ctxselect,
  54.   mgrib_sync,
  55.   mgrib_worldbegin,
  56.   mgrib_worldend,
  57.   mgrib_reshapeviewport,
  58.   mgrib_settransform,
  59.   mg_gettransform,    /* Generic */
  60.   mgrib_identity,
  61.   mgrib_transform,
  62.   mgrib_pushtransform,
  63.   mgrib_poptransform,
  64.   mgrib_pushappearance,
  65.   mgrib_popappearance,
  66.   mgrib_setappearance,
  67.   mgrib_getappearance,
  68.   mgrib_setcamera,
  69.   mgrib_polygon,
  70.   mgrib_polylist,
  71.   mgrib_mesh,
  72.   mgrib_line,
  73.   mgrib_polyline,
  74.   mg_quads,
  75.   mgrib_bezier
  76.   };
  77.  
  78. static mgribcontext *MGRIB;    /* For debugging */
  79.  
  80. int
  81. mgdevice_RIB()
  82. {
  83.   _mgf = mgribfuncs;
  84.   if (_mgc != NULL && _mgc->devno != MGD_RIB)
  85.     _mgc = NULL;
  86.  
  87.   return(0);
  88. }
  89.  
  90. /*-----------------------------------------------------------------------
  91.  * Function:    mgrib_ctxcreate
  92.  * Date:    Thu Jul 18 18:55:18 1991
  93.  * Author:    mbp
  94.  * Notes:    see mg.doc for rest of spec
  95.  */
  96. mgcontext *
  97. mgrib_ctxcreate(int a1, ...)
  98. {
  99.   va_list alist;
  100.   time_t timedate = (time_t)time(0);
  101.     
  102.   _mgc =
  103.     (mgcontext*)(MGRIB = mgrib_newcontext( OOGLNewE(mgribcontext,
  104.         "mgrib_ctxcreate") ));
  105.  
  106.   /* Ensure some sensible default Window */
  107.   WnSet(_mgc->win, WN_XSIZE, 300, WN_YSIZE, 200, WN_END);
  108.  
  109.   /* Default RIB1.0 structure info */
  110.   sprintf(_mgribc->ribscene, "Generic RIB file");
  111.   sprintf(_mgribc->ribcreator, "mgrib driver");
  112.   sprintf(_mgribc->ribfor, getenv("USER"));
  113.   sprintf(_mgribc->ribdate, ctime(&timedate));
  114.   _mgribc->ribdate[24] = '\0'; /* remove the line feed */
  115.   
  116.   va_start(alist, a1);
  117.   _mgrib_ctxset(a1, &alist);
  118.   va_end(alist);
  119.   return _mgc;
  120. }
  121.  
  122. /*-----------------------------------------------------------------------
  123.  * Function:    _mgrib_ctxset
  124.  * Description:    internal ctxset routine
  125.  * Args:    a1: first attribute
  126.  *        *alist: rest of attribute-value list
  127.  * Returns:    nothing
  128.  * Author:    mbp
  129.  * Date:    Fri Sep 20 11:08:13 1991
  130.  * Notes:    mgrib_ctxcreate() and mgrib_ctxset() call this to actually
  131.  *        parse and interpret the attribute list.
  132.  */
  133. void
  134. _mgrib_ctxset(int a1, va_list *alist)
  135. {
  136.   int attr;
  137.  
  138.   for (attr = a1; attr != MG_END; attr = va_arg (*alist, int)) {
  139.     switch (attr) {
  140.     case MG_ApSet:
  141.       {
  142.     Appearance *ap;
  143.  
  144.     ap = _ApSet(NULL, va_arg(*alist, int), alist);
  145.     mgrib_setappearance(ap, MG_MERGE);
  146.     ApDelete(ap);
  147.       }
  148.       break;
  149.     case MG_WnSet:
  150.       _WnSet( _mgc->win, va_arg(*alist, int), alist);
  151.       break;
  152.     case MG_CamSet:
  153.       _CamSet( _mgc->cam, va_arg(*alist, int), alist);
  154.       break;
  155.     case MG_APPEAR:
  156.       mgsetappearance(va_arg(*alist, Appearance *), MG_SET);
  157.       break;
  158.     case MG_WINDOW:
  159.       if (_mgc->win) WnDelete(_mgc->win);
  160.       _mgc->win = va_arg(*alist, WnWindow*);
  161.       RefIncr((Ref*) (_mgc->win));
  162.       break;
  163.     case MG_CAMERA:
  164.       mgrib_setcamera( va_arg(*alist, Camera*) );
  165.       break;
  166.     case MG_SETOPTIONS:
  167.       _mgc->opts |= va_arg(*alist, int);
  168.     case MG_UNSETOPTIONS:
  169.       _mgc->opts &= ~va_arg(*alist, int);
  170.       break;
  171.     case MG_SHOW:
  172.       _mgc->shown = va_arg(*alist, int);
  173.       break;
  174.     case MG_PARENT:
  175.       _mgc->parent = va_arg(*alist, mgcontext*);
  176.       break;
  177.     case MG_BACKGROUND:
  178.       _mgc->background = *va_arg(*alist, ColorA*);
  179.       break;
  180.     case MG_ZNUDGE:
  181.       /* for now, read nothing */
  182.       va_arg(*alist, double);
  183.       break;
  184.  
  185.     case MG_SPACE:   _mgc->space = va_arg(*alist, int); break;
  186.     case MG_NDINFO:  _mgc->NDinfo = va_arg(*alist, void *); break;
  187.     case MG_NDMAP:   _mgc->NDmap = va_arg(*alist, mgmapfunc); break;
  188.  
  189.  
  190.     /* kind of RIB-specific */
  191.     case MG_RIBFILE:
  192. /*        if(_mgribc->rib) fclose(_mgribc->rib); */
  193.     _mgribc->rib = va_arg(*alist, FILE*);
  194.     break;
  195.  
  196.     /* really RIB-specific */
  197.     case MG_RIBLINEMODE:
  198.     _mgribc->line_mode = va_arg(*alist, int);
  199.     break;
  200.     case MG_RIBFORMAT:
  201.     switch( va_arg(*alist, int) ) {
  202.     case MG_RIBASCII:
  203.         _mgribc->render_device |= RMD_ASCII;
  204.         _mgribc->render_device &= ~RMD_BINARY; break;
  205.     case MG_RIBBINARY:
  206.         _mgribc->render_device |= RMD_BINARY;
  207.         _mgribc->render_device &= ~RMD_ASCII; break;
  208.     }
  209.     break;
  210.     case MG_RIBFILEPATH:
  211.     if(_mgribc->rib) fclose(_mgribc->rib);
  212.     strcpy(_mgribc->filepath, va_arg(*alist, char*));
  213.     _mgribc->rib = fopen(_mgribc->filepath,"w+");
  214.     break;
  215.     case MG_RIBDISPLAY:
  216.         _mgribc->display = va_arg(*alist, int);
  217.         break;
  218.     case MG_RIBDISPLAYNAME:
  219.     strcpy(_mgribc->displayname, va_arg(*alist, char*));
  220.         break;
  221.     case MG_RIBBACKING:
  222.         _mgribc->backing = va_arg(*alist, int);
  223.     break;
  224.     case MG_RIBSHADER:
  225.         _mgribc->shader = va_arg(*alist, int);
  226.     break;
  227.     case MG_RIBSCENE:
  228.         strcpy(_mgribc->ribscene, va_arg(*alist, char*));
  229.     break;
  230.     case MG_RIBCREATOR:
  231.         strcpy(_mgribc->ribcreator, va_arg(*alist, char*));
  232.     break;
  233.     case MG_RIBFOR:
  234.         strcpy(_mgribc->ribfor, va_arg(*alist, char*));
  235.     break;
  236.     case MG_RIBDATE:
  237.         strcpy(_mgribc->ribdate, va_arg(*alist, char*));
  238.     break;
  239.     default:
  240.     
  241.         OOGLError (0, "_mgrib_ctxset: undefined option: %d\n", attr);
  242.         return;
  243.         break;
  244.     }
  245.   }
  246.  
  247.   if (_mgc->shown && !_mgribc->born) {
  248.  
  249.     /* open the window */
  250.     mgribwindow(_mgc->win);
  251.     /* rib state is *not* in accordance with appearance state:
  252.        don't set the appearance until worldbegin time */
  253.   }
  254. }
  255.  
  256.  
  257. /*-----------------------------------------------------------------------
  258.  * Function:    mgrib_ctxget
  259.  * Description:    get a context attribute value
  260.  * Args:    attr: the attribute to get
  261.  *        value: place to write attr's value
  262.  * Returns:    1 for success; -1 if attr is invalid
  263.  * Author:    mbp
  264.  * Date:    Fri Sep 20 11:50:25 1991
  265.  * Notes:
  266.  */
  267. int
  268. mgrib_ctxget(int attr, void* value)
  269. {
  270. #define VALUE(type) ((type*)value)
  271.  
  272.   switch (attr) {
  273.  
  274.   /* Attributes common to all MG contexts: */
  275.   case MG_APPEAR:
  276.     *VALUE(Appearance*) = &(_mgc->astk->ap);
  277.     break;
  278.   case MG_CAMERA:
  279.     *VALUE(Camera*) = _mgc->cam;
  280.     break;
  281.   case  MG_WINDOW:
  282.     if(_mgribc->born) {
  283.     /* IT DOESN'T MAKE SENSE TO DO THIS, DOES IT? */
  284.     }
  285.     *VALUE(WnWindow*) = _mgc->win;
  286.     break;
  287.   case MG_PARENT:
  288.     *VALUE(mgcontext*) = _mgc->parent;
  289.     break;
  290.   case MG_SETOPTIONS:
  291.   case MG_UNSETOPTIONS:
  292.     *VALUE(int) = _mgc->opts;
  293.     break;
  294.   case MG_BACKGROUND:
  295.     *VALUE(ColorA) = _mgc->background;
  296.     break;
  297.   case MG_ZNUDGE:
  298.     /* not implemented now */
  299.     *VALUE(int) = 0;
  300.   case MG_SPACE: *VALUE(int) = _mgc->space; break;
  301.   case MG_NDINFO: *VALUE(void *) = _mgc->NDinfo; break;
  302.   case MG_NDMAP:  *VALUE(mgmapfunc) = _mgc->NDmap; break;
  303.  
  304.   /* Attributes specific to RIB contexts: */
  305.   case MG_RIBWINID:
  306.     *VALUE(int) = _mgribc->win;
  307.     break;
  308.   case MG_RIBFILE:
  309.     *VALUE(FILE*) = _mgribc->rib;
  310.      break;
  311.  
  312.   /* Attributes really specific to RI contexts: */
  313.   case MG_RIBLINEMODE:
  314.      *VALUE(int) = _mgribc->line_mode;
  315.      break;
  316.   case MG_RIBFORMAT:
  317.      if(_mgribc->render_device & RMD_ASCII) *VALUE(int) = MG_RIBASCII;
  318.      if(_mgribc->render_device & RMD_BINARY) *VALUE(int) = MG_RIBBINARY;
  319.      break;
  320.   case MG_RIBFILEPATH:
  321.      *VALUE(char *) = _mgribc->filepath;
  322.      break;
  323.   case MG_RIBDISPLAY:
  324.      *VALUE(int) = _mgribc->display;
  325.      break;
  326.   case MG_RIBDISPLAYNAME:
  327.      *VALUE(char *) = _mgribc->displayname;
  328.      break;
  329.   case MG_RIBBACKING:
  330.      *VALUE(int) = _mgribc->backing;
  331.      break;
  332.   case MG_RIBSHADER:
  333.      *VALUE(int) = _mgribc->shader;
  334.      break;
  335.   case MG_RIBSCENE:
  336.      *VALUE(char *) = _mgribc->ribscene;
  337.      break;
  338.   case MG_RIBCREATOR:
  339.      *VALUE(char *) = _mgribc->ribcreator;
  340.      break;
  341.   case MG_RIBFOR:
  342.      *VALUE(char *) = _mgribc->ribfor;
  343.      break;
  344.   case MG_RIBDATE:
  345.      *VALUE(char *) = _mgribc->ribdate;
  346.      break;
  347.   default:
  348.     OOGLError (0, "mgrib_ctxget: undefined option: %d\n", attr);
  349.     return -1;
  350.  
  351.   }
  352.   return 1;
  353.  
  354. #undef VALUE
  355. }
  356.  
  357. /*-----------------------------------------------------------------------
  358.  * Function:    mgribwindow
  359.  * Description:    create a RIB window
  360.  * Args:    *win: the WnWindow structure to realize
  361.  * Returns:    win if success, NULL if not
  362.  * Author:    wisdom, gunn
  363.  * Date:    Fri Sep 20 11:56:31 1991
  364.  * Notes:    makes the RI calls necessary to create a RIB "window"
  365.  *        which is really a virtual window defining Format, Display,
  366.  *        etc.
  367.  */
  368. WnWindow *
  369. mgribwindow(WnWindow *win)
  370. {
  371.   WnPosition wp;
  372.   int xsize, ysize, flag, reconstrain;
  373.   char *name;
  374.   char gver[80];
  375.   double pxloc, pyloc, pxsize, pysize;
  376.   char fullscene[280], fullcreator[280], fullfor[280], fulldate[280];
  377.  
  378.     /* RIB 1.0 structure comments */
  379.     sprintf(fullscene,"Scene %s",_mgribc->ribscene);
  380.     sprintf(fullcreator,"Creator %s",_mgribc->ribcreator);
  381.     sprintf(fullfor,"For %s",_mgribc->ribfor);
  382.     sprintf(fulldate,"CreationDate %s",_mgribc->ribdate);
  383.     mrti(mr_header,"RenderMan RIB-Structure 1.0", mr_nl,
  384.          mr_header, fullscene, mr_nl,
  385.      mr_header, fullcreator, mr_nl,
  386.      mr_header, fulldate, mr_nl,
  387.      mr_header, fullfor, mr_nl,
  388.      mr_header, "Frames 1", mr_nl,    /* always 1 frame*/
  389.      mr_NULL);
  390.  
  391.     /* options */
  392.     if(_mgribc->shader && _mgribc->shadepath) {
  393.     mrti(mr_header, "CapabilitiesNeeded ShadingLanguage", mr_nl,
  394.          mr_embed, "version 3.03", mr_nl,
  395.          mr_option, mr_string, "searchpath", mr_string, "shader",
  396.         mr_nl, mr_embed, "[", mr_string, _mgribc->shadepath,
  397.         mr_embed, "]", mr_nl, mr_nl, mr_NULL);
  398.     } else {
  399.         mrti(mr_embed, "version 3.03", mr_nl, mr_nl, mr_NULL);
  400.     }
  401.         
  402.     /* set display characteristics...*/
  403.     mrti(mr_display, mr_string, _mgribc->displayname, 
  404.          (_mgribc->display == MG_RIBFRAME) ? mr_framebuffer : mr_file, 
  405.          mr_rgb, mr_NULL);
  406.  
  407.     /* window size */
  408.     WnGet(_mgc->win, WN_CURPOS, &wp);
  409.     xsize = wp.xmax - wp.xmin + 1;
  410.     ysize = wp.ymax - wp.ymin + 1;
  411.     mrti(mr_format, mr_int, xsize, mr_int, ysize, mr_float, 1., mr_NULL);
  412.  
  413.     _mgribc->born = 1;
  414.     return(win);
  415. }
  416.  
  417. /*-----------------------------------------------------------------------
  418.  * Function:    mgrib_ctxset
  419.  * Description:    set some context attributes
  420.  * Args:    a1, ...: list of attribute-value pairs
  421.  * Returns:    nothing
  422.  * Author:    mbp
  423.  * Date:    Fri Sep 20 12:00:18 1991
  424.  */
  425. void mgrib_ctxset( int a1, ...  )
  426. {
  427.   va_list alist;
  428.  
  429.   va_start( alist, a1 );
  430.   _mgrib_ctxset(a1, &alist);
  431.   va_end(alist);
  432. }
  433.  
  434.  
  435. /*-----------------------------------------------------------------------
  436.  * Function:    mgrib_feature
  437.  * Description:    report whether mgrib device has a particular feature
  438.  * Args:    feature: the feature to report on
  439.  * Returns:    an int giving info about feature
  440.  * Author:    wisdom
  441.  * Date:    Tue Aug  3 15:38:05 CDT 1993
  442.  * Notes:    -1 means the feature is not present.
  443.  *
  444.  */
  445. int mgrib_feature( int feature )
  446. {
  447.   if(feature == MGF_BEZIER) return 1;
  448.   return(-1);
  449. }
  450.  
  451. /*-----------------------------------------------------------------------
  452.  * Function:    mgrib_ctxdelete
  453.  * Description:    delete a GL context
  454.  * Args:    *ctx: context to delete
  455.  * Returns:    nothing
  456.  * Author:    slevy
  457.  * Date:    Tue Nov 12 10:29:04 CST 1991
  458.  * Notes:    Deleting the current context leaves the current-context
  459.  *        pointer set to NULL.
  460.  */
  461. void mgrib_ctxdelete( mgcontext *ctx )
  462. {
  463. /*  if(_mgribc->rib) fclose(_mgribc->rib); */
  464.  
  465.   if(ctx->devno != MGD_RIB) {
  466.     mgcontext *was = _mgc;
  467.     mgctxselect(ctx);
  468.     mgctxdelete(ctx);
  469.     if(was != ctx)
  470.     mgctxselect(was);
  471.   } else {
  472.     if(((mgribcontext *)ctx)->shadepath)
  473.         free(((mgribcontext *)ctx)->shadepath);
  474.     mg_ctxdelete(ctx);
  475.     if(ctx == _mgc)
  476.     _mgc = NULL;
  477.   }
  478. }
  479.  
  480. /*-----------------------------------------------------------------------
  481.  * Function:    mgrib_ctxselect
  482.  * Description:    select a RIB context --- make it current
  483.  * Args:    *ctx: the context to become current
  484.  * Returns:    0 (why ???)
  485.  * Author:    mbp, wisdom
  486.  * Date:    Fri Sep 20 12:04:41 1991
  487.  */
  488. int
  489. mgrib_ctxselect( mgcontext *ctx )
  490. {
  491.   if(ctx == NULL || ctx->devno != MGD_RIB) {
  492.     return mg_ctxselect(ctx);
  493.   }
  494.  
  495.   _mgc = ctx;
  496.   MGRIB = (mgribcontext *)ctx;
  497.  
  498.   return(0);
  499. }
  500.  
  501. /*-----------------------------------------------------------------------
  502.  * Function:    mgrib_sync
  503.  * Description:    sync
  504.  * Returns:    nothing
  505.  * Author:    wisdom
  506.  * Date:    Mon Aug  2 18:05:41 CDT 1993
  507.  * Notes:    sync with PRMAN not necessary
  508.  */
  509. void
  510. mgrib_sync( void )
  511. {}
  512.  
  513. /*-----------------------------------------------------------------------
  514.  * Function:    mgrib_worldbegin
  515.  * Description:    prepare to draw a frame
  516.  * Returns:    nothing
  517.  * Author:    wisdom, slevy, gunn
  518.  * Date:    Sat Mar  7 16:28:35 GMT-0600 1992
  519.  */
  520. void
  521. mgrib_worldbegin( void )
  522. {
  523.   static Transform cam2ri = {{1, 0,0,0}, {0,1,0,0}, {0,0,-1,0},{0,0,0,1}};
  524.   int persp;
  525.   float halfxfield, halfyfield, aspect, near, far, fov;
  526.   WnWindow *win;
  527.   int xsize, ysize;
  528.   Transform T;
  529.   WnPosition wp;
  530.   char str[256];
  531.   float focallen;
  532.   HPoint3 look;
  533.   Point3 lookat;
  534.  
  535.     /* first, check to see if we need to open the default rib file    */
  536.     /* IT'S NOW POSSIBLE THAT THIS WON'T GET SENT TO A FILE (streams) */
  537.     /* IN WHICH CASE IT WOULD BE WRONG TO OPEN A FILE. MOVE THIS!!    */
  538.     if(!_mgribc->rib)
  539.         _mgribc->rib = fopen(DEFAULT_RIB_FILE, "w+");
  540.     
  541.     /* interpret options...(none exist now) */
  542.  
  543.     /* this will make sure there's nothing left in the rib file */
  544.     /* we cannot use ftruncate because it generates an error on sgi */
  545.     /*ftruncate(fileno(_mgribc->rib), 0);*/
  546.     if (lseek(1, (off_t)0, 0) == (off_t)0 && ftruncate(1, (off_t)0) == -1)
  547.     perror("ftruncate");
  548.          
  549.     mg_worldbegin();
  550.     mg_findcam();
  551.  
  552.     /* Camera is at (in its own coordinates)  (0,0,0).
  553.      * Looking toward vector (0,0,-1)
  554.      * nominally looking at a point (0,0,-focallen)
  555.      */
  556.     CamGet(_mgc->cam, CAM_FOCUS, &focallen);
  557.     look.x = look.y = 0;  look.z = -focallen;   look.w = 1;
  558.     /* Transform to world coordinates */
  559.     HPt3TransPt3(_mgc->C2W, &look, &lookat);    
  560.     /* Now the camera is at _mgc->cpos (this is a Point3), */
  561.     /* looking at lookat (another Point3) */
  562.    
  563.     /* interpret camera ...*/
  564.     CamGet( _mgc->cam, CAM_NEAR, &near);
  565.     CamGet( _mgc->cam, CAM_FAR, &far);
  566.     mrti(mr_clipping, mr_float, near, mr_float, far, mr_NULL);
  567.     CamGet( _mgc->cam, CAM_PERSPECTIVE, &persp);
  568.     mrti(mr_projection, mr_string, persp?"perspective":"orthographic", mr_NULL);
  569.     CamGet( _mgc->cam, CAM_ASPECT, &aspect );
  570.     CamGet( _mgc->cam, CAM_HALFYFIELD, &halfyfield );
  571.     halfxfield = halfyfield * aspect;
  572.     mrti(mr_screenwindow, mr_float, -halfxfield, mr_float, halfxfield,
  573.         mr_float, -halfyfield, mr_float, halfyfield, mr_NULL);
  574.     CamGet( _mgc->cam, CAM_FOV, &fov);
  575.     sprintf(str, "Field of view %g", fov);
  576.     mrti(mr_comment, str, mr_NULL);
  577.     mrti(mr_framebegin, mr_int, 1, mr_nl, mr_NULL);
  578.     
  579.     sprintf(str, "CameraOrientation %.4g %.4g %.4g %.4g %.4g %.4g",
  580.             _mgc->cpos.x,_mgc->cpos.y,_mgc->cpos.z,
  581.         lookat.x,lookat.y,lookat.z);
  582.     mrti(mr_header, str, mr_nl, mr_NULL);
  583.     mrti(mr_identity, mr_NULL);
  584.     mgrib_printmatrix(cam2ri);
  585.  
  586.     mgrib_printmatrix(_mgc->W2C);
  587.  
  588.     /* Lighting Hack (*WAY* OBSOLETE)
  589.      * mg_globallights(_mgc->astk->lighting.lights, 1);
  590.      * if ( (_mgc->astk->lighting.lights != NULL) &&
  591.      * (_mgc->astk->ap.shading != APF_CONSTANT))
  592.      * mgrib_lights(_mgc->astk->lighting.lights, _mgc->astk);
  593.      */
  594.  
  595.     /* RiWorldBegin...*/
  596.     mrti(mr_nl, mr_nl, mr_worldbegin, mr_NULL);
  597.  
  598.     /* if the option is selected, add the background */
  599.     if(_mgribc->backing == MG_RIBDOBG) {
  600.         float halfxbg = far * halfxfield, halfybg = far * halfyfield;
  601.     float farz = -.99 * far;
  602.     Point3 bg[4];
  603.  
  604.     bg[0].x = -halfxbg; bg[0].y = -halfybg; bg[0].z = farz;
  605.     bg[1].x = -halfxbg; bg[1].y =  halfybg; bg[1].z = farz;
  606.     bg[2].x =  halfxbg; bg[2].y =  halfybg; bg[2].z = farz;
  607.     bg[3].x =  halfxbg; bg[3].y = -halfybg; bg[3].z = farz;
  608.     
  609.     mrti(mr_comment, "simulate background color via polygon", mr_NULL);
  610.     mrti(mr_attributebegin, mr_NULL);
  611.     mgrib_printmatrix(_mgc->C2W);
  612.     mrti(mr_surface, mr_constant, mr_NULL);
  613.     mrti(mr_color, mr_parray, 3, &_mgc->background, mr_NULL);
  614.     mrti(mr_polygon, mr_P, mr_parray, 4*3, bg, mr_NULL);
  615.     mrti(mr_attributeend, mr_NULL);
  616.     }            
  617.  
  618.     /* bring ri state into accordance with appearance state */
  619.   
  620.     {
  621.       Appearance *ap = ApCopy( &(_mgc->astk->ap), NULL );
  622.       mgrib_setappearance( ap, MG_SET );
  623.       ApDelete(ap);
  624.     }
  625.  
  626.     /* NOW DONE BY mg_worldbegin()
  627.      *CamView(_mgc->cam, _mgribc->W2S);
  628.      *TmTranslate(T, 1.0, 1.0, 0);
  629.      *TmConcat(_mgribc->W2S,T, _mgribc->W2S);
  630.      */
  631.      
  632.  
  633.     /* NOW DONE BY mg_worldbegin()
  634.      *mgrib_ctxget(MG_WINDOW, &win);
  635.      *WnGet(_mgc->win, WN_CURPOS, &wp);
  636.      *xsize = wp.xmax - wp.xmin + 1;
  637.      *ysize = wp.ymax - wp.ymin + 1;
  638.      *
  639.      *TmScale(T, (double)xsize*.5, (double)ysize*.5, 1.0);
  640.      *TmConcat(_mgribc->W2S,T, _mgribc->W2S);
  641.      *
  642.      *TmCopy(_mgribc->W2S, _mgribc->O2S);
  643.      */
  644. }
  645.  
  646. /*-----------------------------------------------------------------------
  647.  * Function:    mgrib_worldend
  648.  * Description:    finish drawing a frame
  649.  * Returns:    nothing
  650.  * Author:    wisdom
  651.  * Date:    Sat Mar  7 14:47:40 GMT-0600 1992
  652.  */
  653. void
  654. mgrib_worldend( void )
  655. {
  656.     unsigned char *buffer = tokenbuffer;
  657.     mrti(mr_worldend, mr_nl, mr_NULL);
  658.     mrti(mr_frameend, mr_nl, mr_NULL);
  659.     /* now flush the buffer, if appropriate */
  660.     /* mgrib_flushbuffer(); NOW DONE AT HIGHER LEVEL */
  661.  
  662. }
  663.  
  664. /*-----------------------------------------------------------------------
  665.  * Function:    mgrib_reshapeviewport
  666.  * Description:    adjust to a new window size
  667.  * Returns:    nothing
  668.  * Author:    mbp
  669.  * Date:    Fri Sep 20 12:08:30 1991
  670.  * Notes:    adjusts both GL's internal viewport setting, as well as
  671.  *        MG context WnWindow's current position and camera's
  672.  *        aspect ratio.
  673.  */
  674. void
  675. mgrib_reshapeviewport( void )
  676. {
  677.     WnWindow *win;
  678.     WnPosition wp;
  679.     int xsize, ysize;
  680.  
  681.     mgrib_ctxget(MG_WINDOW, &win);    /* Get window; force it to ask
  682.                      * NeXTStep how big the window is
  683.                      */
  684.     WnGet(win, WN_CURPOS, &wp);
  685.     xsize = wp.xmax - wp.xmin + 1;
  686.     ysize = wp.ymax - wp.ymin + 1;
  687.  
  688.     CamSet(_mgc->cam, CAM_ASPECT, (double)xsize/(double)ysize, CAM_END);
  689. }
  690.  
  691. /*-----------------------------------------------------------------------
  692.  * Function:    mgrib_identity
  693.  * Description:    set the current object xform to identity
  694.  * Returns:    nothing
  695.  * Author:
  696.  * Date:
  697.  * Notes:
  698.  *
  699.  */
  700. void
  701. mgrib_identity( void )
  702. {
  703.     mgrib_settransform( TM_IDENTITY );
  704. }
  705.  
  706. /*-----------------------------------------------------------------------
  707.  * Function:    mgrib_transform
  708.  * Description:    premultiply the object xform by T
  709.  * Args:    T
  710.  * Returns:    nothing
  711.  * Author:    mbp
  712.  * Date:    Fri Sep 20 12:24:57 1991
  713.  * Notes:    We use the GL ModelView matrix stack, not the mgcontext's
  714.  *        stack.
  715.  *
  716.  */
  717. void
  718. mgrib_transform( Transform T )
  719. {
  720.     mg_transform(T);
  721.     mgrib_printmatrix(T);
  722.     TmConcat(_mgc->xstk->T, _mgc->W2S, _mgc->O2S);
  723. }
  724.  
  725. /*-----------------------------------------------------------------------
  726.  * Function:    mgrib_pushtransform
  727.  * Description:    push the object xform stack
  728.  * Returns:    nothing (???)
  729.  * Author:    mbp
  730.  * Date:    Fri Sep 20 12:25:43 1991
  731.  * Notes:    We use the GL ModelView matrix stack, not the mgcontext's
  732.  *        stack.
  733.  *
  734.  *        This assumes we're already in MVIEWING mode.
  735.  */
  736. int
  737. mgrib_pushtransform( void )
  738. {
  739.     mg_pushtransform();
  740.     mrti(mr_transformbegin, mr_NULL);
  741. }
  742.  
  743. /*-----------------------------------------------------------------------
  744.  * Function:    mgrib_popransform
  745.  * Description:    pop the object xform stack
  746.  * Returns:    nothing (???)
  747.  * Author:    mbp
  748.  * Date:    Fri Sep 20 12:25:43 1991
  749.  * Notes:    We use the GL ModelView matrix stack, not the mgcontext's
  750.  *        stack.
  751.  *
  752.  *        This assumes we're already in MVIEWING mode.
  753.  */
  754. int
  755. mgrib_poptransform( void )
  756. {
  757.     mg_poptransform();
  758.     mrti(mr_transformend, mr_NULL);
  759.     TmConcat(_mgc->xstk->T, _mgc->W2S, _mgc->O2S);
  760. }
  761.  
  762.  
  763. /*-----------------------------------------------------------------------
  764.  * Function:    mgrib_settransform
  765.  * Description:    set the current object xform to T
  766.  * Args:    T
  767.  * Returns:    nothing
  768.  * Author:    mbp
  769.  * Date:    Fri Sep 20 12:29:43 1991
  770.  * Notes:    
  771.  */
  772. void
  773. mgrib_settransform( Transform T )
  774. {
  775.     mrti(mr_identity, mr_NULL);
  776.     mg_settransform( T );
  777.     TmConcat(_mgc->xstk->T, _mgc->W2S, _mgc->O2S);
  778.     if(T != TM_IDENTITY)
  779.     mgrib_printmatrix(T);
  780. }
  781.  
  782. /*-----------------------------------------------------------------------
  783.  * Function:    mgrib_pushappearance
  784.  * Description:    push the MG context appearance stack
  785.  * Returns:    nothing
  786.  * Author:    mbp
  787.  * Date:    Fri Sep 20 12:54:19 1991
  788.  */
  789. int
  790. mgrib_pushappearance( void )
  791. {
  792.   mg_pushappearance();
  793.   mrti(mr_comment, "push appearance", mr_attributebegin, mr_NULL);
  794. }
  795.  
  796. /*-----------------------------------------------------------------------
  797.  * Function:    mgrib_popappearance
  798.  * Description:    pop the MG context appearance stack
  799.  * Returns:    nothing
  800.  * Author:    
  801.  * Date:    
  802.  * Note:    Note that we do not have to do anything besides
  803.  *        AttributeEnd, because the RenderMan driver retains
  804.  *        the previous state information. 1/13/92 TMM
  805.  */
  806. int
  807. mgrib_popappearance( void )
  808. {
  809.   register struct mgastk *mastk = _mgc->astk;
  810.   register struct mgastk *mastk_next;
  811.  
  812.   if (! (mastk_next=mastk->next)) {
  813.     OOGLError(0, "mggl_popappearance: appearance stack has only 1 entry.\n");
  814.     return;
  815.   }
  816.  
  817.   mrti(mr_comment, "pop appearance", mr_attributeend, mr_NULL);
  818.   mg_popappearance();
  819.  
  820. }
  821.  
  822. /*-----------------------------------------------------------------------
  823.  * Function:    mgrib_setappearance
  824.  * Author:    munzner, mbp, wisdom
  825.  * Date:    Wed Aug  7 01:08:07 1991
  826.  * Notes:    Tossed mgrib_material, just use mgrib_appearance
  827.  *        since shaders depend on both appearance and material 
  828.  *        settings. (4/1/93 TMM)
  829.  */
  830. Appearance *
  831. mgrib_setappearance( Appearance* ap, int mergeflag )
  832. {
  833.   int changed, mat_changed, lng_changed;
  834.   struct mgastk *mastk = _mgc->astk;
  835.   Appearance *ma;
  836.   static float nullarray[] = { 0.0 };
  837.  
  838.   ma = &(mastk->ap);
  839.  
  840.   /* Decide what changes */
  841.   if (mergeflag == MG_MERGE) {
  842.     changed = ap->valid & ~ma->override;
  843.     mat_changed =
  844.       ap->mat ? ap->mat->valid & ~ma->mat->override : 0;
  845.     lng_changed =
  846.       ap->lighting ? ap->lighting->valid & ~ma->lighting->override : 0;
  847.   }
  848.   else {
  849.     changed = ap->valid;
  850.     mat_changed = ap->mat ? ap->mat->valid : 0;
  851.     lng_changed = ap->lighting ? ap->lighting->valid : 0;
  852.   }
  853.  
  854.   mg_setappearance( ap, mergeflag );
  855.  
  856.   /* here is where everything gets set (sort of) */
  857.  
  858.   if(_mgribc->born) {
  859.     mgrib_appearance( mastk, changed, mat_changed);
  860.  
  861.     /* interpret lights ... */
  862.     mgrib_lighting(_mgc->astk, lng_changed);
  863.   }
  864.  
  865. }
  866.  
  867.  
  868. /*-----------------------------------------------------------------------
  869.  * Function:    mgrib_getappearance
  870.  * Description:    return a ptr to current appearance
  871.  * Returns:    ptr to current appearance
  872.  * Author:    mbp
  873.  * Date:    Fri Sep 20 13:00:41 1991
  874.  * Notes:    Applications should not modify the returned appearance
  875.  *        in any way.
  876.  */
  877. Appearance *
  878. mgrib_getappearance()
  879. {
  880.     return &(_mgc->astk->ap);
  881. }
  882.  
  883. /*-----------------------------------------------------------------------
  884.  * Function:    mgrib_setcamera
  885.  * Description:    set the context's camera (pointer)
  886.  * Args:    *cam: the camera to use
  887.  * Returns:    nothing
  888.  * Author:    mbp
  889.  * Date:    Fri Sep 20 13:07:31 1991
  890.  * Notes:    The context stores a pointer to the camera, not a copy
  891.  *        of it.
  892.  */
  893. int
  894. mgrib_setcamera( Camera* cam )
  895. {
  896.   if (_mgc->cam) CamDelete(_mgc->cam);
  897.   _mgc->cam = cam;
  898.   RefIncr((Ref*) cam);
  899. }
  900.  
  901. /*-----------------------------------------------------------------------
  902.  * Function:    mgrib_newcontext
  903.  * Description:    initialize a new mgricontext structure
  904.  * Args:    *ctx: the struct to initialize
  905.  * Returns:    ctx
  906.  * Author:    mbp
  907.  * Date:    Fri Sep 20 13:11:03 1991
  908.  */
  909. mgribcontext *
  910. mgrib_newcontext( mgribcontext *ctx )
  911. {
  912.   static char stdshaderpaths[] =
  913.     ".:shaders:/usr/local/prman/prman/lib/shaders:/NextLibrary/Shaders";
  914.  
  915.   char *geomdata = getenv("GEOMDATA");
  916.  
  917.   mg_newcontext(&(ctx->mgctx));
  918.   ctx->mgctx.devfuncs = &mgribfuncs;
  919.   ctx->mgctx.devno = MGD_RIB;
  920.   ctx->mgctx.astk->ap_seq = 1;
  921.   ctx->mgctx.astk->mat_seq = 1;
  922.   ctx->mgctx.astk->light_seq = 1;
  923.   ctx->born = 0;
  924.   ctx->rib = NULL;
  925.   ctx->backing = MG_RIBDOBG;
  926.   ctx->shader = MG_RIBSTDSHADE;
  927.   ctx->shadepath = NULL;        /* should add context field */
  928.   if(geomdata) {
  929.     char path[512];
  930.     sprintf(path, "%s:%s/shaders", stdshaderpaths, geomdata);
  931.     ctx->shadepath = strdup(path);
  932.   }
  933.  
  934.   /* initalize the token interface */
  935.   if(!tokenbuffer) mrti_init();
  936.   mrti_reset();
  937.  
  938.   ctx->render_device = RMD_ASCII;
  939.   ctx->line_mode = MG_RIBCYLINDER;
  940.  
  941.   return ctx;
  942. }
  943.  
  944. /*-----------------------------------------------------------------------
  945.  * Function:    mgrib_findctx
  946.  * Description: Given a GL window ID, returns the associated mg context.
  947.  * Returns:    mgcontext * for success, NULL if none exists.
  948.  * Author:    slevy
  949.  * Date:    Mon Nov 11 18:33:53 CST 1991
  950.  * Notes:    This is a public routine.
  951.  */
  952. mgcontext *
  953. mgrib_findctx( long winid )
  954. {
  955.   register struct mgcontext *mgc;
  956.  
  957.   for(mgc = _mgclist; mgc != NULL; mgc = mgc->next) {
  958.     if(mgc->devno == MGD_RIB && ((mgribcontext *)mgc)->win == winid)
  959.     return mgc;
  960.   }
  961.   return NULL;
  962. }
  963.  
  964. /*-----------------------------------------------------------------------
  965.  * Function:    mgrib_flushbuffer
  966.  * Description: flushed tokens from buffer to a file
  967.  * Returns:    nothing
  968.  * Author:    wisdom
  969.  * Date:    Mon Jul 26 12:35:45 CDT 1993
  970.  * Notes:    This is a public routine, prototyped in mgrib.h
  971.  */
  972. void
  973. mgrib_flushbuffer()
  974. {
  975.     unsigned char *buffer = tokenbuffer;
  976.     /* do we even want a buffer anymore? why? */
  977.     if(!_mgribc->rib)
  978.         _mgribc->rib = fopen(DEFAULT_RIB_FILE, "w+");
  979.     while(buffer<ptr) putc(*(buffer++), _mgribc->rib);
  980.     fflush(_mgribc->rib);
  981.     mrti_reset(_mgribc->rib);
  982. }
  983.  
  984. /*-----------------------------------------------------------------------
  985.  * Function:    mgrib_terminatebuffer
  986.  * Description: NULL terminates the tokenbuffer, required to support
  987.          NeXTs render panel 
  988.  * Returns:    nothing
  989.  * Author:    wisdom
  990.  * Date:    Mon Jul 26 12:35:45 CDT 1993
  991.  * Notes:    This is a public routine, prototyped in mgrib.h
  992.  */
  993. void
  994. mgrib_terminatebuffer()
  995. {
  996.     *(ptr++) = 0;
  997. }
  998.  
  999. /*-----------------------------------------------------------------------
  1000.  * Function:    mgrib_tokenbuffer
  1001.  * Description: returns through indirection the tokenbuffer an size 
  1002.  * Returns:    char pointer to tokenbuffer
  1003.  * Author:    wisdom
  1004.  * Date:    Mon Jul 26 12:35:45 CDT 1993
  1005.  * Notes:    This is a public routine, prototyped in mgrib.h
  1006.  */
  1007. void
  1008. mgrib_tokenbuffer(char **buffer, int *size)
  1009. {
  1010.     *buffer = (char *)tokenbuffer;
  1011.     *size = ptr - tokenbuffer;
  1012. }
  1013.